import os

from process.process_parse_file import read_paragraphs_images_pdf, read_paragraphs_images_docx, process_parse_file

from util.util_mysql import MySQLVrlab
from util.util_image import load_image_from_path, load_image_from_bytes, calculate_ssim, evaluate_ssim
from util.util_excel import save_to_csv

from score.ScorerPart3 import ScorerPart3
from score.ScorerPart4 import ScorerPart4
from score.ScorerPart5 import ScorerPart5
from score.ScorerPart6 import ScorerPart6
from score.ScorerPart7 import ScorerPart7


# =============================================== 数据清洗相关 =====================================================
def get_reports_dict(path_dir_find):
    dict_reports = {}
    # 递归遍历给定目录及其子目录下的所有文件
    for root, dirs, files in os.walk(path_dir_find):
        for filename in files:
            # 检查文件是否以 .doc, .docx 或 .pdf 结尾，并且以 mj_ 开头
            # if filename.lower().endswith(('.doc', '.docx', '.pdf')) and filename.lower().startswith('mj_'):
            # if filename.lower().endswith('.docx') and filename.lower().startswith('mj_'):
            if filename.lower().endswith('.pdf') and filename.lower().startswith('mj_'):
                try:
                    # 获取 mj_ 到第一个下划线之间的内容作为键
                    parts = filename.split('_', 2)
                    key = parts[0] + '_' + parts[1]
                    # 获取完整的旧文件路径
                    file_path = os.path.join(root, filename)
                    # 如果键已经存在，则将文件路径添加到列表中
                    if key in dict_reports:
                        if isinstance(dict_reports[key]['file_path'], list):
                            dict_reports[key]['file_path'].append(file_path)
                        else:
                            dict_reports[key]['file_path'] = [file_path]
                    else:
                        # 如果键不存在，则创建一个新的条目
                        dict_reports[key] = {'file_path': [file_path]}
                    print(f"file_path: {file_path}")
                except Exception as e:
                    print(f"{filename} 处理出错: {e}")
    return dict_reports


def get_reports_list(path_dir_find):
    list_reports = []
    # 递归遍历给定目录及其子目录下的所有文件
    for root, dirs, files in os.walk(path_dir_find):
        for filename in files:
            # 检查文件是否以 .doc, .docx 或 .pdf 结尾，并且以 mj_ 开头
            # if filename.lower().endswith(('.doc', '.docx', '.pdf')) and filename.lower().startswith('mj_'):
            if filename.lower().endswith(('.docx', '.pdf')) and filename.lower().startswith('mj_'):
            # if filename.lower().endswith('.docx') and filename.lower().startswith('mj_'):
            # if filename.lower().endswith('.pdf') and filename.lower().startswith('mj_'):
                try:
                    # 获取 mj_ 到第一个下划线之间的内容作为键
                    parts = filename.split('_', 2)
                    key = parts[0] + '_' + parts[1]
                    # 获取完整的旧文件路径
                    file_path = os.path.join(root, filename)
                    # 保存记录
                    list_reports.append({
                        "user_name": key,
                        "file_path": file_path})
                    # print(f"file_path: {file_path}")
                except Exception as e:
                    print(f"{filename} 处理出错: {e}")
    return list_reports


def convert_to_dict(records):
    result_dict = {}
    for record in records:
        mysql_id = record[0]
        username = record[1]  # 假设username在记录中的索引为1
        score = record[8]     # 假设score在记录中的索引为8
        evaluation = record[9]  # 假设evaluation在记录中的索引为9
        result_dict[username] = {"score": score, "evaluation": evaluation, "mysql_id": mysql_id}
    return result_dict


def add_report_2_score(list_report, list_score):
    """
    将 list_report 中的 user_name 与 list_score 中的 username 相同的项进行匹配，
    并将匹配的报告路径添加到对应的 list_score 记录中。
    :param list_report: 包含报告信息的列表
    :param list_score: 包含评分信息的列表
    :return: 更新后的 list_score
    """
    # 创建一个字典，用于快速查找 report 信息
    report_dict = {report['user_name']: report for report in list_report}
    # 遍历 list_score，将匹配的 report 信息添加到对应的记录中
    list_score_new = []
    for score in list_score:
        username = score[1]
        if username in report_dict:
            file_path = report_dict[username]['file_path']
            list_score_new.append({
                "id": score[0],
                "user_name": username,
                "score": score[2],
                "file_path": file_path,
            })
    return list_score_new


# =============================================== 处理图片ssim相关 ================================================
# 检查是否有得分图片
def parse_images(list_image, target_image_data):
    ssim_list = []
    for image in list_image:
        image_data = load_image_from_bytes(image)
        ssim = calculate_ssim(image_data, target_image_data)
        # print("ssim:", ssim, evaluate_ssim(ssim))
        ssim_list.append(ssim)
    return ssim_list


# ================================================ 判分类 ==================================================
class Scorer:
    def __init__(self):
        self.scorerPart3 = ScorerPart3()
        self.scorerPart4 = ScorerPart4()
        self.scorerPart5 = ScorerPart5()
        self.scorerPart6 = ScorerPart6()
        self.scorerPart7 = ScorerPart7()

    # 报告判分: 主函数
    def score_report(self, dict_matched_paragraphs, list_matched_images):
        dict_report_score = dict()
        dict_report_score["part3"], dict_report_score["part3_detail"] \
            = self.scorerPart3.score_part_3(dict_matched_paragraphs, list_matched_images)
        dict_report_score["part4"], dict_report_score["part4_detail"] \
            = self.scorerPart4.score_part_4(dict_matched_paragraphs, list_matched_images)
        dict_report_score["part5"], dict_report_score["part5_detail"] \
            = self.scorerPart5.score_part_5(dict_matched_paragraphs, list_matched_images)
        dict_report_score["part6"], dict_report_score["part6_detail"] \
            = self.scorerPart6.score_part_6(dict_matched_paragraphs, list_matched_images)
        dict_report_score["part7"], dict_report_score["part7_detail"] \
            = self.scorerPart7.score_part_7(dict_matched_paragraphs, list_matched_images)
        dict_report_score["final"] = dict_report_score["part3"] + dict_report_score["part4"] \
                                     + dict_report_score["part5"] + dict_report_score["part6"] \
                                     + dict_report_score["part7"]
        return dict_report_score




# =============================================== 主函数 =======================================================
# TODO: 暂无解析.pdf和.doc
def main():
    # 1.从数据库查询已评分记录
    mysqlVrlab = MySQLVrlab("files/config.inf")
    mysqlVrlab.connect()
    list_score = mysqlVrlab.select_scores()
    mysqlVrlab.disconnect()
    # 2.读取所有实验报告
    list_report = get_reports_list(f"E://【2024-10-22】AI判分/10.91.128.2-Tomcat80")
    # 3.填写评分到实验报告的记录
    list_score_new = add_report_2_score(list_report, list_score)
    # 4.每一份报告分块判分
    # list_score_new = list_score_new[:3]
    scorer = Scorer()
    print("len of list_report:", len(list_score_new))
    i = 0
    for score_new in list_score_new:
        i += 1
        print("i:", i)
        path_file = score_new["file_path"]
        print("path_file:", path_file)
        print("id:", score_new["id"], ", user_name:", score_new["user_name"], ", score:", score_new["score"])
        # fixme: 有可能存在解析.docx出问题的情况，以及判分比较图片出问题的情况，需要把try分散到具体功能报错
        try:
            # 解析文件
            is_parse_ok, dict_matched_paragraphs, list_matched_images = process_parse_file(path_file)
            if is_parse_ok is False:
                print("解析文档失败, 请手工判分! path_file:", path_file)
                print("============================================================================================")
                continue
            # 判分
            dict_report_score = scorer.score_report(dict_matched_paragraphs, list_matched_images)
            print("第三部分得分, 当前分数:", dict_report_score["part3"], dict_report_score["part3_detail"])
            print("第四部分得分, 当前分数:", dict_report_score["part4"], dict_report_score["part4_detail"])
            print("第五部分得分, 当前分数:", dict_report_score["part5"], dict_report_score["part5_detail"])
            print("第六部分得分, 当前分数:", dict_report_score["part6"], dict_report_score["part6_detail"])
            print("第七部分得分, 当前分数:", dict_report_score["part7"], dict_report_score["part7_detail"])
            print("结束, 总分数:", dict_report_score["final"], "详情:", dict_report_score)
            # 保存到mysql
            mysqlVrlab.connect()
            result_mysql = {
                "part3": str(dict_report_score["part3"]) + "-(" + str(dict_report_score["part3_detail"]) + ")",
                "part4": str(dict_report_score["part4"]) + "-(" + str(dict_report_score["part4_detail"]) + ")",
                "part5": str(dict_report_score["part5"]) + "-(" + str(dict_report_score["part5_detail"]) + ")",
                "part6": str(dict_report_score["part6"]) + "-(" + str(dict_report_score["part6_detail"]) + ")",
                "part7": str(dict_report_score["part7"]) + "-(" + str(dict_report_score["part7_detail"]) + ")",
                "final": str(dict_report_score["final"]),
            }
            mysqlVrlab.update_remarks(str(result_mysql), score_new["id"])
            mysqlVrlab.disconnect()
            # 保存到excel
            result_csv = {
                "user_name": score_new["user_name"],
                "file_path": score_new["file_path"],
                "score": score_new["score"],
                "score_ai_part_3": str(dict_report_score["part3"]) + "-(" + str(dict_report_score["part3_detail"]) + ")",
                "score_ai_part_4": str(dict_report_score["part4"]) + "-(" + str(dict_report_score["part4_detail"]) + ")",
                "score_ai_part_5": str(dict_report_score["part5"]) + "-(" + str(dict_report_score["part5_detail"]) + ")",
                "score_ai_part_6": str(dict_report_score["part6"]) + "-(" + str(dict_report_score["part6_detail"]) + ")",
                "score_ai_part_7": str(dict_report_score["part7"]) + "-(" + str(dict_report_score["part7_detail"]) + ")",
                "score_ai_final": dict_report_score["final"],
            }
            save_to_csv([result_csv], f"files/test_back_score5_v2.csv")
        except Exception as e:
            print(f"发生错误: {e}")
        print("============================================================================================")




# =============================================== 测试函数 ================================================
# 测试判分单幅图片
def test_score_image():
    # 读取答案得分图片
    target_img_data_4_1 = load_image_from_path(f"files/ans/ans_4_1.png")
    # 每份报告分割出段落和图片
    path_docx = f'C://work/【实验室相关】/【2024-10-22】AI判分/10.91.128.2-Tomcat80/202108/mj_2153507_鏈辩亸_20210817182547.docx'
    dict_matched_paragraphs, list_matched_images = read_paragraphs_images_docx(path_docx)
    # 检查是否有得分图片
    ssim_list = parse_images(list_matched_images, target_img_data_4_1)
    return any(x > 0.5 for x in ssim_list)


# 测试判单个文字段落
def test_score_paragraphs():
    # 每份报告分割出段落和图片
    path_docx = f'C://work/【实验室相关】/【2024-10-22】AI判分/10.91.128.2-Tomcat80/202108/mj_2153507_鏈辩亸_20210817182547.docx'
    dict_matched_paragraphs, list_matched_images = read_paragraphs_images_docx(path_docx)
    # 判每段有没有关键内容
    for key, paras in dict_matched_paragraphs.items():
        print(key)
        for para in paras['word']:
            print(para)
        print("-------------------------------")


# 测试生成回测数据
def test_back_test_data():
    # 1.从数据库查询已评分记录
    mysqlVrlab = MySQLVrlab("files/config.inf")
    mysqlVrlab.connect()
    list_score = mysqlVrlab.select_scores()
    mysqlVrlab.disconnect()
    # 2.读取所有实验报告
    list_report = get_reports_list(f"C://work/【实验室相关】/【2024-10-22】AI判分/10.91.128.2-Tomcat80")
    # 3.填写评分到实验报告的记录
    list_score_2 = add_report_2_score(list_report, list_score)
    print("len of report:", len(list_score_2))
    for score_2 in list_score_2:
        print(score_2)


# 测试单个报告判分 -- docx
def test_score_report_docx():
    # path_docx = f'C://work/【实验室相关】/【2024-10-22】AI判分/10.91.128.2-Tomcat80/202108/mj_2153507_鏈辩亸_20210817182547.docx'
    # path_docx = f'C://work/【实验室相关】/【2024-10-22】AI判分/10.91.128.2-Tomcat80/202110/mj_3758516_鐗涙案楣廮20211014153034.docx'
    path_docx = f'C://work/【实验室相关】/【2024-10-22】AI判分/10.91.128.2-Tomcat80/202311/mj_5008280_鏉庤帋_20231130152106.docx'
    dict_matched_paragraphs, list_matched_images = read_paragraphs_images_docx(path_docx)
    scorer = Scorer()
    dict_report_score = scorer.score_report(dict_matched_paragraphs, list_matched_images)
    print("第三部分得分, 当前分数:", dict_report_score["part3"])
    print("第四部分得分, 当前分数:", dict_report_score["part4"])
    print("第五部分得分, 当前分数:", dict_report_score["part5"])
    print("第六部分得分, 当前分数:", dict_report_score["part6"])
    print("第七部分得分, 当前分数:", dict_report_score["part7"])
    print("结束, 总分数:", dict_report_score["final"], "详情:", dict_report_score)


# 测试单个报告判分 -- pdf
def test_score_report_pdf():
    # path_pdf = 'C://work/【实验室相关】/【2024-10-22】AI判分/10.91.128.2-Tomcat80/202110/mj_3703363_浠ｅ畤_20211027171257.pdf'
    # path_pdf = 'C://work/【实验室相关】/【2024-10-22】AI判分/10.91.128.2-Tomcat80/202401/mj_5046417_鍟嗗崥闂籣20240103203932.pdf'
    path_pdf = 'E://【2024-10-22】AI判分/10.91.128.2-Tomcat80/202110/mj_3880366_寮犲瓙鐎歘20211015144539.pdf'
    dict_matched_paragraphs, list_matched_images = read_paragraphs_images_pdf(path_pdf)
    scorer = Scorer()
    dict_report_score = scorer.score_report(dict_matched_paragraphs, list_matched_images)
    print("第三部分得分, 当前分数:", dict_report_score["part3"])
    print("第四部分得分, 当前分数:", dict_report_score["part4"])
    print("第五部分得分, 当前分数:", dict_report_score["part5"])
    print("第六部分得分, 当前分数:", dict_report_score["part6"])
    print("第七部分得分, 当前分数:", dict_report_score["part7"])
    print("结束, 总分数:", dict_report_score["final"], "详情:", dict_report_score)



if __name__=="__main__":
    # 主函数
    main()
    # 测试流程
    # test_back_test_data()
    # test_score_report_docx()
    # test_score_report_pdf()